/**
 * @Author: 弋嘉鑫
 * @Date: 2021/10/11 14：49 PM
 * @remark: 对远程搜索进行封装，暴露简单的方法，方便使用和回显
 * @example
 * <remote-select v-model="form.licenseNumber" placeholder="选择车辆" :fetch="MsSelectGetRemoteCarno" clearable ></remote-select>
 */
import debounce from 'lodash/debounce';
import isEqual from 'lodash/isEqual';

export default {
    name: 'RemoteSelect',
    props: {
        clue: {
            type: String,
            default: 'value',
        },
        label: {
            type: String,
            default: 'label',
        },
        fetch: {
            type: Function,
        },
        needInit: {
            type: Boolean,
            default: true,
        },
    },
    data() {
        this.fetchData = debounce(this.getData, 300);
        const { options = [] } = this.$attrs;
        this.$watch('$attrs.options', (value, oldVal) => {
            if (!isEqual(value, oldVal)) {
                this.options = value || [];
            }
        });
        return {
            loading: false,
            options,
        };
    },
    methods: {
        async getData(...arg) {
            this.loading = true;
            let result = [];
            if (this.fetch) {
                result = await this.fetch(...arg);
            }
            this.options = Array.isArray(result) ? result : [];
            this.loading = false;
        },
        change(...arg) {
            this.$emit('change', ...arg);
            this.$emit('input', ...arg);
            const selected = this.options.filter((item) => item[this.clue] === arg[0]) || [];
            this.$emit('selected', arg[0], selected[0], this.options);
            this.$nextTick(() => {
                this.dispatch('ElFormItem', 'el.form.change', [arg[0]]);
            });
        },
    },

    render() {
        const attrs = {
            filterable: true,
            remote: true,
            reserveKeyword: true,
            clearable: true,
            loading: this.loading,
            ...this.$attrs,
        };

        // 传入了fetch，则走远端请求
        if (this.fetch) {
            attrs.remoteMethod = this.fetchData;
        }
        const listeners = {
            focus: () => {
                if (this.needInit) {
                    if (!this.$attrs.options || (Array.isArray(this.$attrs.options) && !this.$attrs.options.length)) {
                        this.getData();
                    }
                }
            },
            change: this.change,
            ...this.$listener,
        };
        return (
            <el-select scopedSlots={this.$scopedSlots} props={attrs} on={listeners}>
                {this.options.map((item, index) => (
                    <el-option key={`${item[this.clue]}-${index}`} label={item[this.label]} value={item[this.clue]} disabled={!!item.disabled}>
                        {this.$scopedSlots.options ? (
                            this.$scopedSlots.options({
                                item,
                                label: this.label,
                            })
                        ) : (
                            <span>{item[this.label]}</span>
                        )}
                    </el-option>
                ))}
            </el-select>
        );
    },
};
